package com.ews.onlineexchange.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.PrePersist;
import javax.persistence.PreUpdate;
import javax.persistence.Transient;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.annotations.Where;
import org.hibernate.validator.constraints.Length;

/**
 * 栏目Entity
 * 
 */
@Entity
//@DynamicInsert
//@DynamicUpdate
//@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Category extends DataEntity {

	private static final long	serialVersionUID	= 1L;

	private Category			parent;										// 父级菜单
	private String				module = "article";							// 栏目模型（article：文章；picture：图片；download：下载；link：链接；special：专题）
	private String				name;										// 栏目名称
	private String				image;										// 栏目图片
	private String				href;										// 链接
	private String				target;										// 目标（
																			// _blank、_self、_parent、_top）
	private String				description;								// 描述，填写有助于搜索引擎优化
	private String				keywords;									// 关键字，填写有助于搜索引擎优化
	private boolean				inMenu;										// 是否在导航中显示（1：显示；0：不显示）
	private boolean				inList;										// 是否在分类页中显示列表（1：显示；0：不显示）
	private String				showModes = "0"; 							// 展现方式（
																			// 0:有子栏目显示栏目列表，无子栏目显示内容列表;
																			// 1：首栏目内容列表；
																			// 2：栏目第一条内容）
	private boolean				allowComment;								// 是否允许评论
	private boolean				needAudit;									// 是否需要审核

	private Date				beginDate;									// 开始时间
	private Date				endDate;									// 结束时间
	private String				cnt;										// 信息量
	private String				hits;										// 点击量

	private List<Category>		childList			= new ArrayList<>(); 	// 拥有子分类列表

	private String				aliasName;									//别名

	public String getHits() {
		return hits;
	}

	public void setHits(String hits) {
		this.hits = hits;
	}

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "parent_id")
	@NotFound(action = NotFoundAction.IGNORE)
	public Category getParent() {
		return parent;
	}
	
	@Transient
	public Category getRootParent() {
		if (getParent() == null)
			return null;
		if (getParent().getParent() == null)
			return getParent();
		else 
			return getParent().getRootParent();
	}
	
	@Transient
	public Category getSecParent() {
		if (getParent() == null)
			return null;
		if (getParent().getParent() == null)
			return this;
		return getParent();
	}
	
	@Transient
	public String getParentIds() {
		return id.toString();
	}

	public void setParent(Category parent) {
		this.parent = parent;
	}

	@Length(min = 0, max = 20)
	public String getModule() {
		return module;
	}

	public void setModule(String module) {
		this.module = module;
	}

	@Length(min = 0, max = 100)
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Length(min = 0, max = 255)
	public String getImage() {
		return image;
	}

	public void setImage(String image) {
		this.image = image;
	}

	@Length(min = 0, max = 255)
	public String getHref() {
		return href;
	}

	public void setHref(String href) {
		this.href = href;
	}

	@Length(min = 0, max = 20)
	public String getTarget() {
		return target;
	}

	public Date getBeginDate() {
		return beginDate;
	}

	public void setBeginDate(Date beginDate) {
		this.beginDate = beginDate;
	}

	public Date getEndDate() {
		return endDate;
	}

	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}

	public void setTarget(String target) {
		this.target = target;
	}

	@Length(min = 0, max = 255)
	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	@Length(min = 0, max = 255)
	public String getKeywords() {
		return keywords;
	}

	public void setKeywords(String keywords) {
		this.keywords = keywords;
	}

	public boolean isInMenu() {
		return inMenu;
	}

	public void setInMenu(boolean inMenu) {
		this.inMenu = inMenu;
	}

	public boolean isInList() {
		return inList;
	}

	public void setInList(boolean inList) {
		this.inList = inList;
	}

	@Length(min = 1, max = 1)
	public String getShowModes() {
		return showModes;
	}

	public void setShowModes(String showModes) {
		this.showModes = showModes;
	}

	public boolean isAllowComment() {
		return allowComment;
	}

	public void setAllowComment(boolean allowComment) {
		this.allowComment = allowComment;
	}
	
	public boolean isNeedAudit() {
		return needAudit;
	}

	public void setNeedAudit(boolean needAudit) {
		this.needAudit = needAudit;
	}

	@OneToMany(cascade = { CascadeType.REMOVE }, mappedBy = "parent")
	@Where(clause = "delFlag='" + DEL_FLAG_NORMAL + "'")
	@OrderBy(value = "sort")
	@Fetch(FetchMode.SUBSELECT)
	@NotFound(action = NotFoundAction.IGNORE)
//	@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
	public List<Category> getChildList() {
		return childList;
	}

	public void setChildList(List<Category> childList) {
		this.childList = childList;
	}

	public String getCnt() {
		return cnt;
	}

	public void setCnt(String cnt) {
		this.cnt = cnt;
	}
	
	public String getAliasName() {
		return aliasName;
	}

	public void setAliasName(String aliasName) {
		this.aliasName = aliasName;
	}

	@PrePersist
	public void prePersist() {
		super.prePersist();
		this.setAliasName(this.getName());
	}
	
	@PreUpdate
	private void preSave() {
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((aliasName == null) ? 0 : aliasName.hashCode());
		result = prime * result + (allowComment ? 1231 : 1237);
		result = prime * result + ((beginDate == null) ? 0 : beginDate.hashCode());
		result = prime * result + ((cnt == null) ? 0 : cnt.hashCode());
		result = prime * result + ((description == null) ? 0 : description.hashCode());
		result = prime * result + ((endDate == null) ? 0 : endDate.hashCode());
		result = prime * result + ((hits == null) ? 0 : hits.hashCode());
		result = prime * result + ((href == null) ? 0 : href.hashCode());
		result = prime * result + ((image == null) ? 0 : image.hashCode());
		result = prime * result + (inList ? 1231 : 1237);
		result = prime * result + (inMenu ? 1231 : 1237);
		result = prime * result + ((keywords == null) ? 0 : keywords.hashCode());
		result = prime * result + ((module == null) ? 0 : module.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + (needAudit ? 1231 : 1237);
		result = prime * result + ((parent == null) ? 0 : parent.hashCode());
		result = prime * result + ((showModes == null) ? 0 : showModes.hashCode());
		result = prime * result + ((target == null) ? 0 : target.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Category other = (Category) obj;
		if (aliasName == null) {
			if (other.aliasName != null)
				return false;
		} else if (!aliasName.equals(other.aliasName))
			return false;
		if (allowComment != other.allowComment)
			return false;
		if (beginDate == null) {
			if (other.beginDate != null)
				return false;
		} else if (!beginDate.equals(other.beginDate))
			return false;		
		if (cnt == null) {
			if (other.cnt != null)
				return false;
		} else if (!cnt.equals(other.cnt))
			return false;
		if (description == null) {
			if (other.description != null)
				return false;
		} else if (!description.equals(other.description))
			return false;
		if (endDate == null) {
			if (other.endDate != null)
				return false;
		} else if (!endDate.equals(other.endDate))
			return false;
		if (hits == null) {
			if (other.hits != null)
				return false;
		} else if (!hits.equals(other.hits))
			return false;
		if (href == null) {
			if (other.href != null)
				return false;
		} else if (!href.equals(other.href))
			return false;
		if (image == null) {
			if (other.image != null)
				return false;
		} else if (!image.equals(other.image))
			return false;
		if (inList != other.inList)
			return false;
		if (inMenu != other.inMenu)
			return false;
		if (keywords == null) {
			if (other.keywords != null)
				return false;
		} else if (!keywords.equals(other.keywords))
			return false;
		if (module == null) {
			if (other.module != null)
				return false;
		} else if (!module.equals(other.module))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (needAudit != other.needAudit)
			return false;
		if (parent == null) {
			if (other.parent != null)
				return false;
		} else if (!parent.equals(other.parent))
			return false;
		if (showModes == null) {
			if (other.showModes != null)
				return false;
		} else if (!showModes.equals(other.showModes))
			return false;
		if (target == null) {
			if (other.target != null)
				return false;
		} else if (!target.equals(other.target))
			return false;
		return true;
	}
}